package cn.amarone.wineblog.config.security;

import cn.amarone.wineblog.common.constant.CaptchaConst;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * 连接数据库，校验验证码，获取实际要登陆的用户名和密码将其放入UsernamePasswordAuthenticationToken
 *
 * <pre>
 * UsernamePasswordAuthenticationFilter是AbstractAuthenticationProcessingFilter
 * 针对使用用户名和密码进行身份验证而定制化的一个过滤器。
 * 其添加是在调用http.formLogin()时作用，默认的登录请求pattern为"/login"，(这里我们改为了 /doLogin)
 * 并且为POST请求。当我们登录的时候，也就是匹配到loginProcessingUrl，
 * 这个过滤器就会委托认证管理器authenticationManager来验证登录。
 * </pre>
 */
public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {


  public static final String SUPPER_METHOD = "POST";

  private static final boolean POST_ONLY = true;

  @Override
  public Authentication attemptAuthentication(
      HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {

    if (POST_ONLY && !SUPPER_METHOD.equals(request.getMethod())) {
      throw new AuthenticationServiceException(
          "Authentication method not supported: " + request.getMethod());
    }

    String username = obtainUsername(request);
    String password = obtainPassword(request);



    String verCode = obtainCode(request);
    String verKey = obtainCodeKey(request);

    UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
        username, password);

    // Allow subclasses to set the "details" property
    setDetails(request, authRequest);

    return super.attemptAuthentication(request, response);
  }

  /**
   * 获取验证码
   *
   * @param request
   * @return
   */
  protected String obtainCode(HttpServletRequest request) {
    return request.getParameter(CaptchaConst.VER_CODE);
  }

  /**
   * 获取验证码key
   *
   * @param request
   * @return
   */
  protected String obtainCodeKey(HttpServletRequest request) {
    return request.getParameter(CaptchaConst.VER_KEY);
  }
}
